﻿using System.IO;
using System.Windows.Forms;

namespace Engine.FileFormats3D.C11Undercover
{
    public class C11UcLvlFile
    {
        #region Public Fields

        public readonly byte[] data;

        #endregion Public Fields

        #region Public Constructors

        public C11UcLvlFile()
        {
            this.data = new byte[32];
        }

        #endregion Public Constructors

        #region Public Properties

        public float DirectionX { get; set; }
        public float DirectionY { get; set; }
        public float DirectionZ { get; set; }
        public int int1 { get; set; }
        public int int2 { get; set; }
        public int int3 { get; set; }
        public int int4 { get; set; }
        public int int5 { get; set; }
        public int int6 { get; set; }
        public float PosX { get; set; }
        public float PosY { get; set; }
        public float PosZ { get; set; }
        public float value1 { get; set; }
        public float value10 { get; set; }
        public float value11 { get; set; }
        public float value12 { get; set; }
        public float value2 { get; set; }
        public float value3 { get; set; }
        public float value4 { get; set; }
        public float value5 { get; set; }
        public float value6 { get; set; }
        public float value7 { get; set; }
        public float value8 { get; set; }
        public float value9 { get; set; }

        #endregion Public Properties

        #region Public Methods

        public static C11UcLvlFile FromFile(string filename)
        {
            FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read);
            BinaryReader br = new BinaryReader(fs);

            C11UcLvlFile c11UcLvl = new C11UcLvlFile();

            c11UcLvl.PosX = br.ReadSingle(); // 0
            c11UcLvl.PosY = br.ReadSingle(); // 4
            c11UcLvl.PosZ = br.ReadSingle(); // 8

            c11UcLvl.DirectionX = br.ReadSingle(); // 12
            c11UcLvl.DirectionY = br.ReadSingle(); // 16
            c11UcLvl.DirectionZ = br.ReadSingle(); // 20

            c11UcLvl.value1 = br.ReadSingle(); // 24 // könnte auch (short)0 + (short)-32768 sein oder 00 00 00 128
            c11UcLvl.value2 = br.ReadSingle(); // 28
            c11UcLvl.value3 = br.ReadSingle(); //32

            c11UcLvl.value4 = br.ReadSingle(); // 36 // kleine werte zwischen -1 un  1
            c11UcLvl.value5 = br.ReadSingle(); // 40
            c11UcLvl.value6 = br.ReadSingle(); // 44

            c11UcLvl.value7 = br.ReadSingle(); // 48 kleine werte zwischen -1 un  1 (Light Vector for Shaders)
            c11UcLvl.value8 = br.ReadSingle(); // 52
            c11UcLvl.value9 = br.ReadSingle(); // 56

            c11UcLvl.int1 = br.ReadInt32(); // 0000 0000
            c11UcLvl.int2 = br.ReadInt32(); // 0000 0100
            c11UcLvl.int3 = br.ReadInt32(); // DDF5 FF00

            c11UcLvl.int4 = br.ReadInt32(); // Farben ?
            c11UcLvl.int5 = br.ReadInt32(); // Farben ?
            c11UcLvl.int6 = br.ReadInt32(); // Farben ?

            c11UcLvl.value10 = br.ReadSingle(); // Wert um die 6.4989
            c11UcLvl.value11 = br.ReadSingle(); // ca 0.202
            c11UcLvl.value12 = br.ReadSingle(); // 0

            for (int i = 0; i < c11UcLvl.data.Length; i++)
            {
                c11UcLvl.data[i] = br.ReadByte();
            }

            br.Close();
            fs.Close();

            return c11UcLvl;
        }

        public void ToFile(string filename)
        {
            FileStream fs = new FileStream(filename, FileMode.Create);
            BinaryWriter bw = new BinaryWriter(fs);
            //BinaryReader br = new BinaryReader(fs);

            //C11UcLvlFile c11UcLvl = new C11UcLvlFile();

            bw.Write((float)this.PosX); //c11UcLvl.PosX = br.ReadSingle();
            bw.Write((float)this.PosY); //c11UcLvl.PosY = br.ReadSingle();
            bw.Write((float)this.PosZ); //c11UcLvl.PosZ = br.ReadSingle();

            bw.Write((float)this.DirectionX); //c11UcLvl.DirectionX = br.ReadSingle();
            bw.Write((float)this.DirectionY);  //c11UcLvl.DirectionY = br.ReadSingle();
            bw.Write((float)this.DirectionZ);  //c11UcLvl.DirectionZ = br.ReadSingle();

            bw.Write((float)this.value1);//c11UcLvl.value1 = br.ReadSingle(); // könnte auch (short)0 + (short)-32768 sein oder 00 00 00 128
            bw.Write((float)this.value2); //c11UcLvl.value2 = br.ReadSingle();
            bw.Write((float)this.value3); //c11UcLvl.value3 = br.ReadSingle();

            bw.Write((float)this.value4);   //c11UcLvl.value4 = br.ReadSingle(); // kleine werte zwischen -1 un  1
            bw.Write((float)this.value5); //c11UcLvl.value5 = br.ReadSingle();
            bw.Write((float)this.value6); //c11UcLvl.value6 = br.ReadSingle();

            bw.Write((float)this.value7);   //c11UcLvl.value7 = br.ReadSingle(); // kleine werte zwischen -1 un  1
            bw.Write((float)this.value8);  //c11UcLvl.value8 = br.ReadSingle();
            bw.Write((float)this.value9);  //c11UcLvl.value9 = br.ReadSingle();

            bw.Write((int)this.int1); //c11UcLvl.int1 = br.ReadInt32(); // 0000 0000
            bw.Write((int)this.int2); //c11UcLvl.int2 = br.ReadInt32(); // 0000 0100
            bw.Write((int)this.int3); //c11UcLvl.int3 = br.ReadInt32(); // DDF5 FF00

            bw.Write((int)this.int4); //c11UcLvl.int4 = br.ReadInt32(); // Farben ?
            bw.Write((int)this.int5); //c11UcLvl.int5 = br.ReadInt32(); // Farben ?
            bw.Write((int)this.int6); //c11UcLvl.int6 = br.ReadInt32(); // Farben ?

            bw.Write((float)this.PosX);  //c11UcLvl.value10 = br.ReadSingle(); // Wert um die 6.4989
            bw.Write((float)this.PosX);  //c11UcLvl.value11 = br.ReadSingle(); // ca 0.202
            bw.Write((float)this.PosX);  //c11UcLvl.value12 = br.ReadSingle(); // 0

            bw.Write(this.data); //c11UcLvl.data = br.ReadBytes(c11UcLvl.data.Length);

            if (bw.BaseStream.Position != 128)
                MessageBox.Show("LVL-File should be 128 Bytes long. this is: " + bw.BaseStream.Position.ToString());

            bw.Close();
            //br.Close();
            fs.Close();
        }

        #endregion Public Methods
    }
}